<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Rainbow</title>
  <link rel="stylesheet" type="text/css" href="importer.min.css">
</head>
<body>
  <div class="wrapper">
    <canvas class="canvas" id="canvas" width="500" height="300">
      Your browser does not support HTML5 Canvas API
    </canvas>
  </div>
  <script src="../../scripts/utils.js"></script>
  <script>
  'use strict'

  function Particles (canvas) {
    // instance data
    this.canvas = canvas
    this.ctx = canvas.getContext('2d')
    this.alpha = 0.6
    this.width = window.innerWidth
    this.height = window.innerHeight
    this.pr = window.devicePixelRatio || 1
    this.particles = []

    this.canvas.width = this.width * this.pr
    this.canvas.height = this.height * this.pr

    this.ctx.scale(this.pr, this.pr)
    this.ctx.globalAlpha = this.alpha
  }

  Particles.prototype.downloadImage = function () {
    var _this = this
    var img = new Image()
    img.src = '../../img/pikaqiu_01.png'

    img.onload = function () {
      var maxLength = Math.max(_this.width, _this.height)
      var printWidth = maxLength * 0.3
      // 335/370是该图片的宽高比
      var printHeight = printWidth * 335 / 370
      // 让绘制到canvas上的图片位于中间位置，所需给图片左上角设定的起始坐标
      var printX = (_this.width - printWidth) / 2
      var printY = (_this.height - printHeight) / 2
      _this.ctx.drawImage(img, 0, 0, img.width, img.height, printX, printY, printWidth, printHeight)
      var canvasData = _this.ctx.getImageData(0, 0, _this.width, _this.height)

      setTimeout(_this.collectParticles.bind(_this, canvasData), 300)

      setInterval(_this.collectParticles.bind(_this, canvasData), 6000)
    }
  }

  Particles.prototype.collectParticles = function (canvasData) {
    var _this = this

    var particles = []
    var idxInDataArr = 0
    var data = canvasData.data

    for (var i = 0; i < canvasData.width; i+=6) {
      for (var j = 0; j < canvasData.height; j+=6) {
        // 计算(i, j)坐标上的像素点对应RGBA值中R值在data数组中的索引
        idxInDataArr = (j * canvasData.width + i) * 4
        // 判断透明度alpha值是否符合要求
        if (data[idxInDataArr + 3] > 50) {
          var r = data[idxInDataArr]
          var g = data[idxInDataArr + 1]
          var b = data[idxInDataArr + 2]
          var a = data[idxInDataArr + 3]
          var offsetX = i
          var offsetY = j
          var rgba = 'rgba(' + r + ', ' + g + ', ' + b + ', ' + a + ')'
          particles.push(new Particle(offsetX / _this.pr, offsetY / _this.pr, rgba))
        }
      }
    }

    _this.particles = particles

    var animationId
    void function loop () {
      _this.draw()
      animationId = requestAnimationFrame(function () {
        loop()
      })
    }()
    // 不清除掉animationId的话，因为requestAnimationFrame被不停调用，且collectParticles方法也是周期性调用，会导致没重复几次collectParticles方法页面就很卡了
    setTimeout(function () {
      cancelAnimationFrame(animationId)
    }, 6000)
  }

  Particles.prototype.draw = function () {
    var _this = this
    var particles = _this.particles

    _this.ctx.clearRect(0, 0, _this.width, _this.height)

    for (var i = 0, len = particles.length; i < len; i++) {
      var curParticle = particles[i]
      _this.ctx.save()
      _this.ctx.beginPath()
      _this.ctx.arc(curParticle.getX(), curParticle.getY(), curParticle.getRadius(), 0, Math.PI * 2)
      _this.ctx.fillStyle = curParticle.rgba
      _this.ctx.fill()
      _this.ctx.restore()
    }
  }

  function Particle (offsetX, offsetY, rgba) {
    this.x = offsetX
    this.y = offsetY
    this.rgba = rgba
    this.vectorX = (Math.random() - 0.5) * 4
    this.vectorY = -5 + (Math.random() - 0.5) * 2
    this.gravity = 0.1
  }

  Particle.prototype.getX = function () {
    var _this = this
    _this.x += _this.vectorX
    return _this.x
  }

  Particle.prototype.getY = function () {
    var _this = this
    _this.gravity -= 0.01
    _this.vectorY += _this.gravity
    _this.y += _this.vectorY
    if(_this.gravity < 0) {
      _this.gravity = 0.1
    }
    return _this.y
  }

  Particle.prototype.getRadius = function () {
    return 2
  }

  function canvasSupport () {
    return !!document.createElement('canvas').getContext
  }

  void function launchApp () {
    if (!canvasSupport()) {
      return
    }

    var canvas = document.getElementById('canvas')
    new Particles(canvas).downloadImage()
  }()
  </script>
</body>
</html>
